﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Infinity.Types
{
	/// <summary>
	/// Intervallum reprezentációja
	/// </summary>
	public abstract class Range<T> : IRange<T> where T : struct, IComparable<T>
	{
		protected Range(T start, Nullable<T> end)
		{
			Start = start;
			End = end;
		}

		/// <summary>
		/// Intervallum alsó határa
		/// </summary>
		public T Start { get; protected set; }

		/// <summary>
		/// Intervallum felső határa
		/// </summary>
		public Nullable<T> End { get; protected set; }

		public abstract T Next(T value);

		public IEnumerator<T> GetEnumerator()
		{
			if (End.HasValue)
			{
				bool condition = true;

				for (var index = Start; condition; index = Next(index))
				{
					condition = !index.Equals(End.Value);
					yield return index;
				}
			}
			else
			{
				for (var index = Start;; index = Next(index))
				{
					yield return index;
				}
			}
		}

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}


		public bool IsElementOf(T value)
		{
			return value.CompareTo(Start) >= 0 && (!End.HasValue || value.CompareTo(End.Value) <= 0);
		}
	}
}